package spherical_tessellation_test;

import java.util.ArrayList;

public class SurfaceTriangle {

	private static final int THRESHOLD_DEPTH = 5;

	private CoordinateVector v0, v1, v2;
	private int depth;
	private SurfaceTriangle subTriangle1, subTriangle2, subTriangle3,
			subTriangle4;
	private boolean subTrianglesGenerated;

	public SurfaceTriangle(CoordinateVector v0, CoordinateVector v1,
			CoordinateVector v2, int depth) {
		this.v0 = v0;
		this.v1 = v1;
		this.v2 = v2;
		this.depth = depth;
		this.subTrianglesGenerated = false;
	}

	public CoordinateVector getV0() {
		return v0;
	}

	public CoordinateVector getV1() {
		return v1;
	}

	public CoordinateVector getV2() {
		return v2;
	}

	public void updateTriangleList(ArrayList<SurfaceTriangle> triangleList) {
		int currentDistanceValue = this.computeDistanceValue();
		if (currentDistanceValue < this.depth) {
			triangleList.remove(this);
		} else if (currentDistanceValue == this.depth) {
			if (!triangleList.contains(this)) {
				triangleList.add(this);
			}
		} else {
			if (!triangleList.contains(this)) {
				triangleList.add(this);
			}
			if (!this.subTrianglesGenerated) {
				this.generateSubTriangles();
			}
			subTriangle1.updateTriangleList(triangleList);
			subTriangle2.updateTriangleList(triangleList);
			subTriangle3.updateTriangleList(triangleList);
			subTriangle4.updateTriangleList(triangleList);
		}
	}

	private void generateSubTriangles() {
		// generate midpoints
		CoordinateVector w0 = this.v1.createMidpointVector(this.v2,
				this.depth > SurfaceTriangle.THRESHOLD_DEPTH);
		CoordinateVector w1 = this.v0.createMidpointVector(this.v2,
				this.depth > SurfaceTriangle.THRESHOLD_DEPTH);
		CoordinateVector w2 = this.v0.createMidpointVector(this.v1,
				this.depth > SurfaceTriangle.THRESHOLD_DEPTH);

		// form midpoints and base points into sub triangles
		subTriangle1 = new SurfaceTriangle(this.v0, w2, w1, this.depth + 1);
		subTriangle2 = new SurfaceTriangle(this.v1, w0, w2, this.depth + 1);
		subTriangle3 = new SurfaceTriangle(this.v2, w1, w0, this.depth + 1);
		subTriangle4 = new SurfaceTriangle(w0, w1, w2, this.depth + 1);
	}

	private int computeDistanceValue() {
		float distanceAverage = (CameraModel.getInstance().getPosition()
				.distance(this.v0.getWorldCoordinate())
				+ CameraModel.getInstance().getPosition().distance(
						this.v1.getWorldCoordinate()) + CameraModel
				.getInstance().getPosition().distance(
						this.v2.getWorldCoordinate())) / 3.0f;
		return (int) Math.sqrt(1.0f / distanceAverage);
	}

}
